Skip to content

fix(deno): Handle reader.closed rejection from releaseLock() in streaming#20187

Merged
andreiborza merged 3 commits intodevelopfrom
ab/deno-reader
Apr 10, 2026
Merged

fix(deno): Handle reader.closed rejection from releaseLock() in streaming#20187
andreiborza merged 3 commits intodevelopfrom
ab/deno-reader

Conversation

@andreiborza
Copy link
Copy Markdown
Member

This PR replaces reader.closed.finally(() => onDone()) with reader.closed.then(() => onDone(), () => onDone()) in monitorStream.

Per the WHATWG Streams spec, reader.releaseLock() rejects reader.closed when the promise is still pending. .finally() propagates that rejection as an unhandled promise rejection, while .then(f, f) suppresses it by handling both the fulfilled and rejected cases.

I was not able to reproduce the error directly on my deno version but this should prevent the issue.

Closes: #20177

…treaming

Replace `reader.closed.finally(() => onDone())` with
`reader.closed.then(() => onDone(), () => onDone())` in `monitorStream`.

Per the WHATWG Streams spec, `reader.releaseLock()` rejects `reader.closed`
when the promise is still pending. `.finally()` propagates that rejection as
an unhandled promise rejection, while `.then(f, f)` suppresses it by handling
both the fulfilled and rejected cases.

Closes: #20177
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 10, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Core

  • Add enableTruncation option to Google GenAI integration by andreiborza in #20184
  • Add enableTruncation option to Anthropic AI integration by andreiborza in #20181
  • Add enableTruncation option to LangGraph integration by andreiborza in #20183
  • Add enableTruncation option to LangChain integration by andreiborza in #20182
  • Add enableTruncation option to OpenAI integration by andreiborza in #20167
  • Export a reusable function to add tracing headers by JPeer264 in #20076

Deps

  • Bump axios from 1.13.5 to 1.15.0 by dependabot in #20180
  • Bump hono from 4.12.7 to 4.12.12 by dependabot in #20118
  • Bump defu from 6.1.4 to 6.1.6 by dependabot in #20104

Other

  • (cloudflare) Propagate traceparent to RPC calls - via fetch by JPeer264 in #19991

Bug Fixes 🐛

Deno

  • Handle reader.closed rejection from releaseLock() in streaming by andreiborza in #20187
  • Avoid inferring invalid span op from Deno tracer by Lms24 in #20128

Other

  • (ci) Prevent command injection in ci-metadata workflow by fix-it-felix-sentry in #19899
  • (e2e) Add op check to waitForTransaction in React Router e2e tests by copilot-swe-agent in #20193
  • (node-integration-tests) Fix flaky kafkajs test race condition by copilot-swe-agent in #20189

Internal Changes 🔧

Deps

  • Bump hono from 4.12.7 to 4.12.12 in /dev-packages/e2e-tests/test-applications/cloudflare-hono by dependabot in #20119
  • Bump axios from 1.13.5 to 1.15.0 in /dev-packages/e2e-tests/test-applications/nestjs-basic by dependabot in #20179

Other

  • (bugbot) Add rules to flag test-flake-provoking patterns by Lms24 in #20192
  • (deps-dev) Bump vite from 7.2.0 to 7.3.2 in /dev-packages/e2e-tests/test-applications/tanstackstart-react by dependabot in #20107
  • (react) Remove duplicated test mock by s1gr1d in #20200
  • (size-limit) Bump failing size limit scenario by Lms24 in #20186
  • Add automatic flaky test detector by nicohrubec in #18684

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 10, 2026

size-limit report 📦

Path Size % Change Change
@sentry/browser 25.72 kB - -
@sentry/browser - with treeshaking flags 24.21 kB - -
@sentry/browser (incl. Tracing) 42.73 kB - -
@sentry/browser (incl. Tracing, Profiling) 47.35 kB - -
@sentry/browser (incl. Tracing, Replay) 81.54 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 71.11 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 86.25 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 98.45 kB - -
@sentry/browser (incl. Feedback) 42.51 kB - -
@sentry/browser (incl. sendFeedback) 30.39 kB - -
@sentry/browser (incl. FeedbackAsync) 35.38 kB - -
@sentry/browser (incl. Metrics) 27.04 kB - -
@sentry/browser (incl. Logs) 27.18 kB - -
@sentry/browser (incl. Metrics & Logs) 27.86 kB - -
@sentry/react 27.48 kB - -
@sentry/react (incl. Tracing) 45.05 kB - -
@sentry/vue 30.56 kB - -
@sentry/vue (incl. Tracing) 44.59 kB - -
@sentry/svelte 25.74 kB - -
CDN Bundle 28.41 kB - -
CDN Bundle (incl. Tracing) 43.75 kB - -
CDN Bundle (incl. Logs, Metrics) 29.78 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 44.83 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 68.59 kB - -
CDN Bundle (incl. Tracing, Replay) 80.64 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 81.66 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 86.17 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 87.2 kB - -
CDN Bundle - uncompressed 82.99 kB - -
CDN Bundle (incl. Tracing) - uncompressed 129.77 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 87.14 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 133.19 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 210.12 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 246.65 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 250.05 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 259.56 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 262.95 kB - -
@sentry/nextjs (client) 47.47 kB - -
@sentry/sveltekit (client) 43.2 kB - -
@sentry/node-core 57.86 kB +0.02% +7 B 🔺
@sentry/node 174.86 kB +0.01% +9 B 🔺
@sentry/node - without tracing 97.97 kB +0.03% +22 B 🔺
@sentry/aws-serverless 115.22 kB +0.02% +18 B 🔺

View base workflow run

Copy link
Copy Markdown
Member

@s1gr1d s1gr1d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a good approach - looks good 👍

@andreiborza andreiborza enabled auto-merge (squash) April 10, 2026 08:17
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7f65c39. Configure here.

e.preventDefault();
unhandledRejection = e;
};
globalThis.addEventListener('unhandledrejection', handler);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unhandled rejection listener registered after triggering action

Low Severity

The unhandledrejection event listener is registered on line 46, after reader.releaseLock() on line 39 which is the action that would trigger the rejection. If the fix were ever reverted to .finally(), the unhandled rejection event could fire before the listener is attached, causing the assertEquals(unhandledRejection, undefined, ...) assertion to pass incorrectly — hiding the regression the test is meant to catch. The listener needs to be set up before reader.releaseLock() to reliably detect unhandled rejections. Also, the test uses setTimeout(resolve, 50) which is a sleep-in-test pattern; a more deterministic signal would be preferable.

Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 7f65c39. Configure here.

@andreiborza andreiborza merged commit 2af59be into develop Apr 10, 2026
38 checks passed
@andreiborza andreiborza deleted the ab/deno-reader branch April 10, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reader was released and can no longer be used to monitor the stream's closedness.

2 participants